package com.dj.xbirdie

import android.content.DialogInterface
import android.os.Bundle
import android.util.Log
import android.view.Menu
import android.view.MenuInflater
import android.view.MenuItem
import android.view.View
import android.widget.*
import androidx.activity.viewModels
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.widget.AppCompatCheckBox
import androidx.lifecycle.ViewModelProvider
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager2.widget.ViewPager2
import com.dj.xbirdie.adapter.AdvancePager2Adapter
import com.dj.xbirdie.adapter.HistoryListAdapter
import com.dj.xbirdie.adapter.SubjectListAdapter
import com.dj.xbirdie.databinding.ActivityMainBinding
import com.dj.xbirdie.entity.HistoryEntity
import com.dj.xbirdie.entity.MqttEntity
import com.dj.xbirdie.events.onTopicEventInterface
import com.dj.xbirdie.utils.Md5Utils
import com.dj.xbirdie.viewmodels.MqttViewModel
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayoutMediator
import kotlinx.android.synthetic.main.activity_main.view.*
import org.eclipse.paho.android.service.MqttAndroidClient
import org.eclipse.paho.client.mqttv3.*
import java.util.*


class MainActivity : AppCompatActivity(), onTopicEventInterface {
    val item = listOf<String>("At most once(0)", "At least once(1)", "Exactly once(2)");
    var clientId = "";
    var subqos = 0;

    var willQos = 0;

    var subjectList = mutableListOf<MutableMap<String, Any>>();
    var historyList = mutableListOf<HistoryEntity>();
    var pubqos = 0;
    var mqttAndroidClient: MqttAndroidClient? = null


    private lateinit var historyRecyclerView: RecyclerView
    private lateinit var historyViewAdapter: RecyclerView.Adapter<*>
    private lateinit var historyViewManager: RecyclerView.LayoutManager

    private lateinit var recyclerView: RecyclerView
    private lateinit var viewAdapter: RecyclerView.Adapter<*>
    private lateinit var viewManager: RecyclerView.LayoutManager

    private lateinit var binding: ActivityMainBinding

    @ExperimentalStdlibApi
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)


        Log.i("Main", "重建view")

        binding = ActivityMainBinding.inflate(layoutInflater)
        val view = binding.root
        setContentView(view);

        binding.mqttModel=ViewModelProvider(this).get(MqttViewModel::class.java);


//        val actionBar = getActionBar()
//        actionBar!!.setBackgroundDrawable(ColorDrawable(Color.RED))

        var tablayout = findViewById<TabLayout>(R.id.advanceTabLayout)
        var viewPager = findViewById<ViewPager2>(R.id.advanceViewPager2Layout);

        var views = mutableListOf<Int>();
        views.add(R.layout.advance_auth);
        views.add(R.layout.advance_will);
        views.add(R.layout.advance_ssl);

        viewPager.adapter = AdvancePager2Adapter(views);

        TabLayoutMediator(tablayout, viewPager) { tab, position ->
            tab.text = AdvancePager2Adapter.list.get(position);
            viewPager.setCurrentItem(tab.position, true)
        }.attach()

        viewManager = LinearLayoutManager(this, RecyclerView.HORIZONTAL, false);
        viewAdapter = SubjectListAdapter(this,subjectList);
//        viewAdapter.onTopicEventInterface(this)

        recyclerView = findViewById<RecyclerView>(R.id.subjectTopicList1).apply {
            setHasFixedSize(true);
            layoutManager = viewManager;
            adapter = viewAdapter;
        }



        historyViewManager = LinearLayoutManager(this, RecyclerView.VERTICAL, false);
        historyViewAdapter = HistoryListAdapter(historyList);
//        viewAdapter.onTopicEventInterface(this)

        historyRecyclerView = findViewById<RecyclerView>(R.id.historyList).apply {
            setHasFixedSize(true);
            layoutManager = historyViewManager;
            adapter = historyViewAdapter;
        }



        clientId = Md5Utils.md5(Date().time.toString());

//        findViewById<Button>(R.id.randomBtn).setOnClickListener { v ->
//            run {
//                findViewById<EditText>(R.id.clientIdInput).setText(
//                    Md5Utils.md5(Date().time.toString())
//                );
//            }
//        }
//
//        findViewById<Button>(R.id.randomCleanBtn).setOnClickListener { v ->
//            run {
//                findViewById<EditText>(R.id.clientIdInput).setText("");
//            }
//        }

        findViewById<TextView>(R.id.publishButton).setOnLongClickListener {v ->
            run {
                var layout = findViewById<LinearLayout>(R.id.publishInputLayout)
                if (layout.visibility == View.VISIBLE) {
                    layout.visibility = View.GONE;
                } else {
                    layout.visibility = View.VISIBLE;
                }
                true
            }
        }

        findViewById<TextView>(R.id.connectBtn).setOnLongClickListener {v ->
            run {
                var advancelayout = findViewById<LinearLayout>(R.id.advanceLayout)
                if (advancelayout.visibility == View.VISIBLE) {
                    advancelayout.visibility = View.GONE;
                } else {
                    advancelayout.visibility = View.VISIBLE;
                }
                true
            }
        }
        findViewById<TextView>(R.id.connectBtn).setOnClickListener { v ->
            run {
                if (mqttAndroidClient == null || !mqttAndroidClient!!.isConnected) {
                    connect();
                } else {
                    disconnect();
                }
            }
        }

        findViewById<TextView>(R.id.subjectButton).setOnClickListener { v ->
            run {
                var topic = findViewById<EditText>(R.id.subjectTopicInput).text.toString();
                var qos = findViewById<TextView>(R.id.subjectQos).text;

                if (!subjectList.stream().filter { p -> p.get("name") == topic }
                        .findFirst().isPresent) {
                    subjectList.add(mutableMapOf(Pair("name", topic),Pair("color",this.resources.getColor(R.color.colorPrimary))))
                    mqttAndroidClient!!.subscribe(topic, subqos);
                    findViewById<EditText>(R.id.publishTopicInput).text =
                        findViewById<EditText>(R.id.subjectTopicInput).text;
                }
                viewAdapter.notifyDataSetChanged();
                Toast.makeText(this, "connect", Toast.LENGTH_LONG).show();
            }
        }

        findViewById<TextView>(R.id.publishButton).setOnClickListener { v ->
            run {
                var topic = findViewById<EditText>(R.id.publishTopicInput).text.toString();
                var msg = findViewById<EditText>(R.id.publishPayloadInput).text.toString();
                val retained = findViewById<CheckBox>(R.id.retained).isChecked;
                var m = MqttMessage(msg.encodeToByteArray());
                mqttAndroidClient!!.publish(topic, m.payload, pubqos, retained);
                Toast.makeText(this, "publish", Toast.LENGTH_LONG).show();
            }
        }


        findViewById<TextView>(R.id.subjectQos).setOnClickListener { v ->
            run {
                val a = AlertDialog.Builder(this);
                a.setTitle("SELECT SUBJECT QOS")
                a.setItems(item.toTypedArray(), { dialog, which ->
                    subqos = which
                    findViewById<TextView>(R.id.subjectQos).text = "Qos:" + which;
                });
                val a1 = a.create();
                a1.show();
            }
        }

        findViewById<TextView>(R.id.publishQos).setOnClickListener { v ->
            run {
                val a = AlertDialog.Builder(this);
                a.setTitle("SELECT PUBLISH QOS")
                a.setItems(item.toTypedArray(), DialogInterface.OnClickListener { dialog, which ->
                    pubqos = which
                    findViewById<TextView>(R.id.publishQos).text =which.toString();
                });
                val a1 = a.create();
                a1.show();
            }
        }
    }

    fun disconnect(): Unit {
        mqttAndroidClient!!.disconnect();
    }

    @ExperimentalStdlibApi
    fun connect(): Unit {

        val host = findViewById<EditText>(R.id.hostInput).text.toString();

        mqttAndroidClient = MqttAndroidClient(applicationContext, host, clientId)


        mqttAndroidClient!!.setCallback(object : MqttCallbackExtended {
            override fun connectComplete(
                reconnect: Boolean,
                serverURI: String
            ) {
                findViewById<TextView>(R.id.connectBtn).setTextColor(getResources().getColor(R.color.colorSuccess) );
//                findViewById<TextView>(R.id.connectBtn).setText(R.string.connectSuccess);

                findViewById<TextView>(R.id.subjectButton).isEnabled = true;
                findViewById<TextView>(R.id.subjectButton).setTextColor(getResources().getColor(R.color.colorSuccess) );


                findViewById<TextView>(R.id.publishButton).isEnabled = true;
                findViewById<TextView>(R.id.publishButton).setTextColor(getResources().getColor(R.color.colorSuccess) );

                Toast.makeText(applicationContext, "connect", Toast.LENGTH_LONG).show();
            }

            override fun connectionLost(cause: Throwable?) {
                findViewById<TextView>(R.id.connectBtn).setTextColor(getResources().getColor(R.color.colorFail));
                findViewById<TextView>(R.id.connectBtn).setText(R.string.connectError);

                findViewById<TextView>(R.id.subjectButton).isEnabled = false;

                findViewById<TextView>(R.id.publishButton).isEnabled = false;

                findViewById<TextView>(R.id.subjectButton).setTextColor(getResources().getColor(R.color.colorFail) );
                findViewById<TextView>(R.id.publishButton).setTextColor(getResources().getColor(R.color.colorFail) );


                Toast.makeText(applicationContext, "disconnect", Toast.LENGTH_LONG).show();
            }

            @Throws(Exception::class)
            override fun messageArrived(
                topic: String,
                message: MqttMessage
            ) {

                historyList.add(0,HistoryEntity(Date(), topic, message));
                historyViewAdapter.notifyDataSetChanged();
//               findViewById<TextView>(R.id.logView).text= Date().toLocaleString()+": "+topic+": "+String(message.payload)+"\r\n"+findViewById<TextView>(R.id.logView).text

            }

            override fun deliveryComplete(token: IMqttDeliveryToken) {}
        })

        val mqttConnectOptions = MqttConnectOptions()
//       var msg1=findViewById<EditText>(R.id.willTopicPayloadInput).text.toString();
//       mqttConnectOptions.setWill(findViewById<EditText>(R.id.willTopicInput).text.toString(), msg1.encodeToByteArray(), willQos, true);
//       mqttConnectOptions.userName=findViewById<EditText>(R.id.usernameInput).text.toString();
//       mqttConnectOptions.password=findViewById<EditText>(R.id.passwordInput).text.toString().toCharArray();
        mqttConnectOptions.isAutomaticReconnect =
            findViewById<AppCompatCheckBox>(R.id.autoReconnect).isChecked
        mqttConnectOptions.isCleanSession =
            findViewById<AppCompatCheckBox>(R.id.cleanSession).isChecked
        System.out.println(mqttConnectOptions)
        try {
            //addToHistory("Connecting to " + serverUri);
//                    Toast.makeText(applicationContext, "Connecting to ", Toast.LENGTH_LONG).show();
            mqttAndroidClient!!.connect(
                mqttConnectOptions,
                null,
                object : IMqttActionListener {
                    override fun onSuccess(asyncActionToken: IMqttToken) {
                        val disconnectedBufferOptions =
                            DisconnectedBufferOptions()
                        disconnectedBufferOptions.isBufferEnabled = true
                        disconnectedBufferOptions.bufferSize = 100
                        disconnectedBufferOptions.isPersistBuffer = false
                        disconnectedBufferOptions.isDeleteOldestMessages = false
                        mqttAndroidClient!!.setBufferOpts(disconnectedBufferOptions)
                        Toast.makeText(applicationContext, "reconnect", Toast.LENGTH_LONG).show();
                    }

                    override fun onFailure(
                        asyncActionToken: IMqttToken,
                        exception: Throwable
                    ) {

                    }
                })
        } catch (ex: MqttException) {
            ex.printStackTrace()
        }
    }


    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        val inflater: MenuInflater = menuInflater
        inflater.inflate(R.menu.main_menu, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        // Handle item selection
        return when (item.itemId) {
            R.id.help -> {
                handleHelp()
                true
            }
            R.id.version -> {
                System.out.println("点击了版本按钮")
                val builder = AlertDialog.Builder(this)
                builder.setMessage(R.string.versionV1)
                // Create the AlertDialog object and return it
                builder.create()
                builder.show();
                return true;
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    private fun handleHelp() {
        System.out.println("click help menu")
    }

    override fun subject(topic: String?) {
        TODO("Not yet implemented")
    }

    override fun unSubject(topic: String?) {
        TODO("Not yet implemented")
    }

}